<template>
  <div>
    <div v-if="userLoading" class="ai-loading-full">
      <div class="ai-loading"><span class="dot"></span><span class="dot"></span><span class="dot"></span></div>
      <div style="text-align:center;color:#888;margin-top:12px;">正在加载用户信息和历史会话...</div>
    </div>
    <div v-else class="ai-chat-container">
      <!-- 移动端菜单按钮 -->
      <button class="mobile-menu-btn" @click="toggleSidebar">
        <i class="fas fa-bars"></i>
      </button>

      <!-- 左侧功能栏 -->
      <div class="sidebar" :class="{ 'collapsed': isSidebarCollapsed, 'mobile-active': isMobileSidebarActive }">
        <!-- 收缩按钮 -->
        <button class="collapse-btn" @click="toggleSidebar">
          <i :class="isSidebarCollapsed ? 'fas fa-chevron-right' : 'fas fa-chevron-left'"></i>
        </button>

        <!-- 新建对话按钮 -->
        <button class="new-chat-btn" @click="createNewChat">
          <i class="fas fa-plus"></i>
          <span v-if="!isSidebarCollapsed">新建对话</span>
        </button>

        <!-- 模型选择 -->
        <div class="model-selector" v-if="!isSidebarCollapsed">
          <select v-model="selectedModel" class="model-select">
            <option value="deepseek-v3-250324">DeepSeek V3</option>
            <option value="gpt-3.5-turbo">GPT-3.5</option>
            <option value="gpt-4">GPT-4</option>
          </select>
        </div>

        <!-- 对话历史列表 -->
        <div class="chat-history">
          <h3 v-if="!isSidebarCollapsed">对话历史</h3>
          <div class="history-list">
            <div
              v-for="chat in chatHistory"
              :key="chat.id"
              class="history-item"
              :class="{ active: currentSessionId === chat.id }"
              @click="switchChat(chat.id)"
            >
              <i class="fas fa-comment"></i>
              <span class="chat-title" v-if="!isSidebarCollapsed">{{ chat.title }}</span>
              <span class="chat-time" v-if="!isSidebarCollapsed">{{ formatTime(chat.lastTime) }}</span>
            </div>
          </div>
        </div>
        <!-- 设置icon在底部 -->
        <div class="sidebar-footer">
          <button class="settings-btn" @click="showSettings = true">
            <i class="fas fa-cog"></i>
          </button>
        </div>
      </div>

      <!-- 移动端遮罩层 -->
      <div v-if="isMobileSidebarActive" class="mobile-overlay" @click="closeMobileSidebar"></div>

      <!-- 右侧对话区域 -->
      <div class="chat-area">
        <!-- 连接状态和错误提示 -->
        <div v-if="error" class="error-message">
          {{ error }}
          <button class="close-error" @click="error = null">
            <i class="fas fa-times"></i>
          </button>
        </div>

        <!-- 对话内容 -->
        <div class="messages" ref="messagesContainer">
          <div v-for="message in currentMessages" :key="message.id" class="message" :class="message.role">
            <div class="message-content">
              <div class="message-header">
                <span class="role">{{ message.role === 'user' ? '我' : 'AI' }}</span>
                <span class="time">{{ formatTime(message.time) }}</span>
                <!-- AI消息右上角操作icon -->
                <template v-if="message.role === 'assistant'">
                  <span class="msg-icons">
                    <!-- 播放icon，仅html代码块时显示，isStreaming时禁用 -->
                    <i v-if="isHtmlBlock(message)" class="fas fa-play run-html-icon" :class="{disabled: message.isStreaming}" :title="message.isStreaming ? '等待输出完成' : '在线运行'" @click="runHtmlFromMessage(message)" :disabled="message.isStreaming"></i>
                    <i class="fas fa-copy" @click="copyContent(message.content)" title="复制"></i>
                    <i class="fas fa-sync-alt" @click="retryMessage(message)" title="重新回答"></i>
                  </span>
                </template>
              </div>
              <!-- markdown 渲染 -->
              <div class="text" v-html="renderMarkdown(message.content)"></div>
              <!-- 推荐问题 -->
              <div v-if="message.role === 'assistant' && message.suggestedQuestions && message.suggestedQuestions.length > 0" class="suggested-questions">
                <div class="suggested-title">
                  <i class="fas fa-lightbulb"></i>
                  <span>猜你想问</span>
                </div>
                <div class="questions-list">
                  <div v-for="(question, index) in message.suggestedQuestions" 
                       :key="index" 
                       class="question-item"
                       @click="askSuggestedQuestion(question)">
                    <i class="fas fa-comment-dots"></i>
                    <span>{{ question }}</span>
                  </div>
                </div>
              </div>
              <!-- AI消息底部提示 -->
              <div v-if="message.role === 'assistant'" class="ai-warning">
                <div class="warning-icon">
                  <i class="fas fa-exclamation-circle"></i>
                </div>
                <span class="warning-text">AI生成内容，请注意甄别真假</span>
              </div>
              <div v-if="message.role === 'assistant' && message.isStreaming" class="typing-indicator">
                <span></span><span></span><span></span>
              </div>
            </div>
          </div>
          <!-- AI长回复等待时的加载动画 -->
          <div v-if="isLoading && !streamingMessage" class="ai-loading">
            <span class="dot"></span><span class="dot"></span><span class="dot"></span>
          </div>
        </div>

        <!-- 输入区域 -->
        <div class="input-area">
          <!-- 文件上传和MCP服务选择 -->
          <div class="input-options">
            <div class="left-options">
              <div class="file-upload">
      
                <label for="file-upload">
                  <i class="fas fa-paperclip"></i> 添加文件
                </label>
                <span v-if="selectedFiles.length" class="file-count">
                  {{ selectedFiles.length }}个文件
                </span>
              </div>
              <div class="workflow-entry">
                <router-link to="/workflow" class="workflow-btn">
                  <i class="fas fa-project-diagram"></i>
                  工作流
                </router-link>
              </div>
            </div>
            <div class="mcp-service">
              <label>
                <input type="checkbox" v-model="useMcpService">
                MCP服务
                <!-- 连接状态点 -->
                <span class="status-dot" :class="connectionStatus"></span>
              </label>
            </div>
          </div>

          <!-- 输入框 -->
          <div class="input-box">
            <textarea
              v-model="userInput"
              placeholder="输入消息..."
              @keydown.enter.prevent="sendMessage"
              :disabled="isLoading || connectionStatus !== 'connected'"
            ></textarea>
            <button 
              class="send-btn" 
              @click="sendMessage"
              :disabled="isLoading || !userInput.trim() || connectionStatus !== 'connected'"
              :class="{ 'sending': isLoading }"
            >
              <i class="fas" :class="isLoading ? 'fa-spinner fa-spin' : 'fa-paper-plane'"></i>
            </button>
          </div>
        </div>
      </div>
      <!-- 设置弹窗 -->
      <div v-if="showSettings" class="settings-modal-mask" @click.self="showSettings = false">
        <div class="settings-modal" :class="{fullscreen: settingsFullscreen}">
          <div class="modal-macbar">
            <span class="mac-dot mac-dot-red" @click="showSettings = false"></span>
            <span class="mac-dot mac-dot-yellow"></span>
            <span class="mac-dot mac-dot-green" @click="settingsFullscreen = !settingsFullscreen"></span>
          </div>
          <div class="modal-body">
            <div class="modal-menu">
              <div :class="['modal-menu-item', {active: settingsTab === 'mcp'}]" @click="settingsTab = 'mcp'">
                MCP服务配置
              </div>
              <div :class="['modal-menu-item', {active: settingsTab === 'prefs'}]" @click="settingsTab = 'prefs'">
                偏好设置
              </div>
            </div>
            <div class="modal-content-area">
              <div v-if="settingsTab === 'mcp'">
                <h4>MCP服务配置</h4>
                <div class="settings-form">
                  <!-- 名称 -->
                  <div class="form-group">
                    <label class="required">名称</label>
                    <input type="text" v-model="mcpSettings.name" placeholder="MCP服务器" class="form-input">
                  </div>
                  
                  <!-- 描述 -->
                  <div class="form-group">
                    <label>描述</label>
                    <textarea v-model="mcpSettings.description" placeholder="描述信息..." class="form-input" rows="3"></textarea>
                  </div>
                  
                  <!-- 类型 -->
                  <div class="form-group">
                    <label class="required">类型</label>
                    <select v-model="mcpSettings.type" class="form-input">
                      <option value="stdio">标准输入/输出 (stdio)</option>
                    </select>
                  </div>
                  
                  <!-- 命令 -->
                  <div class="form-group">
                    <label class="required">命令</label>
                    <input type="text" v-model="mcpSettings.command" placeholder="uvx or npx" class="form-input">
                  </div>
                  
                  <!-- 参数 -->
                  <div class="form-group">
                    <label>参数</label>
                    <div class="args-list">
                      <div v-for="(arg, index) in mcpSettings.args" :key="index" class="arg-item">
                        <input type="text" v-model="mcpSettings.args[index]" placeholder="参数值" class="form-input">
                        <button @click="removeArg(index)" class="remove-btn">
                          <i class="fas fa-times"></i>
                        </button>
                      </div>
                      <button @click="addArg" class="add-arg-btn">
                        <i class="fas fa-plus"></i>
                        添加参数
                      </button>
                    </div>
                  </div>
                  
                  <!-- 环境变量 -->
                  <div class="form-group">
                    <label>环境变量</label>
                    <div class="env-list">
                      <div v-for="(env, index) in mcpSettings.env" :key="index" class="env-item">
                        <input type="text" v-model="env.key" placeholder="KEY" class="form-input env-key">
                        <input type="text" v-model="env.value" placeholder="value" class="form-input">
                        <button @click="removeEnv(index)" class="remove-btn">
                          <i class="fas fa-times"></i>
                        </button>
                      </div>
                      <button @click="addEnv" class="add-env-btn">
                        <i class="fas fa-plus"></i>
                        添加环境变量
                      </button>
                    </div>
                  </div>
                  
                  <!-- 超时 -->
                  <div class="form-group">
                    <label>超时（秒）</label>
                    <input type="number" v-model="mcpSettings.timeout" placeholder="60" class="form-input">
                  </div>
                </div>
              </div>
              <div v-else-if="settingsTab === 'prefs'">
                <h4>偏好设置</h4>
                <div class="modal-placeholder">此处填写偏好设置项...</div>
              </div>
            </div>
          </div>
        </div>
      </div>
      <div v-if="showHtmlRunner" class="html-runner-modal-mask" @click.self="showHtmlRunner = false">
        <div class="html-runner-modal">
          <div class="modal-header">
            <span class="modal-title"><i class="fas fa-play"></i> HTML在线运行</span>
            <button class="modal-close" @click="showHtmlRunner = false"><i class="fas fa-times"></i></button>
          </div>
          <iframe :srcdoc="htmlToRun" frameborder="0" class="html-runner-iframe"></iframe>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
import markdownit from 'markdown-it';
import hljs from 'highlight.js';
import 'highlight.js/styles/github.css';
import websocketService from '@/services/websocket';
const md = markdownit({
  highlight: function (str, lang) {
    if (lang && hljs.getLanguage(lang)) {
      try {
        return '<pre class="hljs"><code>' +
          hljs.highlight(str, { language: lang, ignoreIllegals: true }).value +
          '</code></pre>';
      } catch (__) {}
    }
    return '<pre class="hljs"><code>' + md.utils.escapeHtml(str) + '</code></pre>';
  }
});

export default {
  name: 'AiChatView',
  data() {
    return {
      isSidebarCollapsed: false,
      isMobileSidebarActive: false,
      selectedModel: 'deepseek-v3-250324',
      chatHistory: [],
      currentSessionId: localStorage.getItem('currentSessionId'),
      currentMessages: [],
      temperature: 0.7,
      maxLength: 2000,
      userInput: '',
      isLoading: false,
      selectedFiles: [],
      useMcpService: false,
      error: null,
      connectionStatus: 'disconnected', // 'disconnected', 'connecting', 'connected'
      streamingMessage: null,
      streamInterval: null,
      showSettings: false,
      settingsTab: 'mcp',
      settingsFullscreen: false,
      showHtmlRunner: false,
      htmlToRun: '',
      userId: null,
      userLoading: true,
      mcpSettings: {
        name: '',
        description: '',
        type: 'stdio',
        command: '',
        args: [],
        env: [],
        timeout: 60
      }
    }
  },
  computed: {
    connectionStatusText() {
      switch (this.connectionStatus) {
        case 'connecting':
          return '正在连接...';
        case 'connected':
          return '已连接';
        case 'disconnected':
          return '连接已断开';
        default:
          return '未知状态';
      }
    }
  },
  created() {
    this.prepareUserAndData();
  },
  beforeUnmount() {
    websocketService.removeMessageHandler(this.handleWebSocketMessage);
    websocketService.disconnect();
    if (this.streamInterval) {
      clearInterval(this.streamInterval);
    }
  },
  methods: {
    async prepareUserAndData() {
      // 1. 校验token
      const token = localStorage.getItem('token');
      if (!token) {
        this.$router.push('/auth');
        return;
      }
      // 2. 获取用户信息
      this.userLoading = true;
      try {
        const res = await fetch('/api/auth/info', {
          headers: { 'Authorization': token }
        });
        if (!res.ok) throw new Error('登录已失效');
        const data = await res.json();
        if (!data.data || !data.data.id) throw new Error('登录已失效');
        this.userId = data.data.id;
        // 3. 加载历史会话
        await this.loadSessions();
        // 4. 建立WebSocket连接
        await this.initWebSocket();
        this.userLoading = false;
      } catch (e) {
        //this.$router.push('/auth');
      }
    },
    async initWebSocket() {
      this.connectionStatus = 'connecting';
      try {
        // 携带token建立连接
        await websocketService.connect({ token: localStorage.getItem('token') });
        this.connectionStatus = 'connected';
        websocketService.addMessageHandler(this.handleWebSocketMessage);
      } catch (error) {
        this.connectionStatus = 'disconnected';
        this.error = '连接服务器失败，请稍后重试';
      }
    },
    handleWebSocketMessage(message) {
      console.log('收到WebSocket消息:', message);
      switch (message.type) {
        case 'chat_response':
        case 'ark_response':
          if (message.sessionId) {
            this.currentSessionId = message.sessionId;
          }
          if (!this.streamingMessage) {
            this.streamingMessage = {
              id: Date.now(),
              role: 'assistant',
              content: '',
              time: new Date(),
              isStreaming: true,
              suggestedQuestions: message.suggestedQuestions || []
            };
            this.currentMessages.push(this.streamingMessage);
            this.startStreaming(message.content);
          } else if (message.suggestedQuestions) {
            this.streamingMessage.suggestedQuestions = message.suggestedQuestions;
          }
          break;

        case 'error':
          console.error('收到错误消息:', message);
          this.error = message.content;
          this.isLoading = false;
          this.stopStreaming();
          break;

        case 'connection_status':
          console.log('连接状态更新:', message);
          this.connectionStatus = message.content;
          break;
      }
    },
    startStreaming(content) {
      let index = 0;
      this.streamInterval = setInterval(() => {
        if (index < content.length) {
          this.streamingMessage.content += content[index];
          index++;
          this.scrollToBottom();
        } else {
          this.stopStreaming();
        }
      }, 50); // 每50ms输出一个字符
    },
    stopStreaming() {
      if (this.streamInterval) {
        clearInterval(this.streamInterval);
        this.streamInterval = null;
      }
      if (this.streamingMessage) {
        this.streamingMessage.isStreaming = false;
        this.streamingMessage = null;
      }
      this.isLoading = false;
    },
    scrollToBottom() {
      this.$nextTick(() => {
        const container = this.$refs.messagesContainer;
        if (container) {
          container.scrollTop = container.scrollHeight;
        }
      });
    },
    async loadSessions() {
      const res = await fetch(`/api/chat/history/sessions?userId=${this.userId}`);
      this.chatHistory = await res.json();
      if (this.chatHistory.length > 0) {
        this.switchChat(this.chatHistory[0].id);
      }
    },
    async switchChat(sessionId) {
      this.currentSessionId = sessionId;
      localStorage.setItem('currentSessionId', sessionId);
      const res = await fetch(`/api/chat/history/sessions/${sessionId}/messages`);
      const messages = await res.json();
      this.currentMessages = messages.map(msg => ({
        id: msg.id,
        role: msg.role,
        content: msg.content,
        time: msg.createdAt
      }));
    },
    async createNewChat() {
      // 创建新会话时不设置标题，等待第一条消息
      const res = await fetch(`/api/chat/history/sessions`, {
        method: 'POST',
        headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
        body: `userId=${this.userId}&title=新对话`
      });
      const session = await res.json();
      this.currentSessionId = session.id;
      localStorage.setItem('currentSessionId', session.id);
      this.currentMessages = [];
      this.loadSessions();
    },
    sendMessage() {
      if (!this.userInput.trim() || this.isLoading) return;
      const message = {
        type: 'chat_message',
        content: this.userInput,
        model: this.selectedModel,
        temperature: this.temperature,
        maxLength: this.maxLength,
        useMcpService: this.useMcpService,
        files: this.selectedFiles,
        sessionId: this.currentSessionId
      };
      const userMessage = {
        id: Date.now(),
        role: 'user',
        content: this.userInput,
        time: new Date()
      };
      this.currentMessages.push(userMessage);
      this.isLoading = true;
      websocketService.send(message);
      this.userInput = '';
      this.selectedFiles = [];
      this.scrollToBottom();
    },
    formatMessage(content) {
      if (!content) return '';
      // 将换行符转换为<br>标签
      return content.replace(/\n/g, '<br>');
    },
    formatTime(date) {
      if (!date) return '';
      const d = new Date(date);
      return d.toLocaleTimeString('zh-CN', { hour: '2-digit', minute: '2-digit' });
    },
    handleFileUpload(event) {
      this.selectedFiles = Array.from(event.target.files);
    },
    handleClickOutside(event) {
      const sidebar = this.$el.querySelector('.sidebar')
      
      if (this.isSidebarCollapsed && 
          !sidebar.contains(event.target)) {
        this.isSidebarCollapsed = false
      }
    },
    renderMarkdown(content) {
      if (!content) return '';
      // 不再插入run按钮
      return md.render(content);
    },
    copyContent(content) {
      if (!content) return;
      navigator.clipboard.writeText(content);
      this.$message && this.$message.success ? this.$message.success('已复制') : alert('已复制');
    },
    retryMessage(message) {
      if (!message) return;
      this.userInput = message.content;
      this.sendMessage();
    },
    mounted() {
      // 让"在线运行"按钮生效
      window.__runHtmlCode = (btn) => {
        const code = decodeURIComponent(btn.parentNode.querySelector('.html-raw').textContent);
        this.htmlToRun = code;
        this.showHtmlRunner = true;
      };
    },
    // 检查内容是否为html代码块
    isHtmlBlock(content) {
      if (!content) return false;
      return /```html[\s\S]*?```/i.test(content);
    },
    // 从消息内容提取html代码并运行
    runHtmlFromMessage(message) {
      console.log('[runHtmlFromMessage] called with message:', message);
      if (message.isStreaming) {
        console.log('[runHtmlFromMessage] message is streaming, abort.');
        return;
      }
      if (!message || !message.content) {
        console.log('[runHtmlFromMessage] message or content is empty.');
        return;
      }
      const match = message.content.match(/```html[\s\S]*?```/i);
      console.log('[runHtmlFromMessage] match:', match);
      if (match) {
        let code = match[0].replace(/^```html[\r\n]*/i, '').replace(/```$/, '');
        console.log('[runHtmlFromMessage] extracted code:', code);
        this.htmlToRun = code;
        this.showHtmlRunner = true;
        console.log('[runHtmlFromMessage] showHtmlRunner set to true');
      } else {
        console.log('[runHtmlFromMessage] no html code block found in content.');
      }
    },
    toggleSidebar() {
      if (window.innerWidth <= 768) {
        this.isMobileSidebarActive = !this.isMobileSidebarActive;
      } else {
        this.isSidebarCollapsed = !this.isSidebarCollapsed;
      }
    },
    closeMobileSidebar() {
      this.isMobileSidebarActive = false;
    },
    handleResize() {
      if (window.innerWidth > 768) {
        this.isMobileSidebarActive = false;
      }
    },
    askSuggestedQuestion(question) {
      this.userInput = question;
      this.sendMessage();
    },
    addArg() {
      this.mcpSettings.args.push('');
    },
    removeArg(index) {
      this.mcpSettings.args.splice(index, 1);
    },
    addEnv() {
      this.mcpSettings.env.push({ key: '', value: '' });
    },
    removeEnv(index) {
      this.mcpSettings.env.splice(index, 1);
    }
  },
  watch: {
    currentMessages: {
      handler() {
        // 滚动到底部
        this.$nextTick(() => {
          const container = this.$refs.messagesContainer
          if (container) {
            container.scrollTop = container.scrollHeight
          }
        })
      },
      deep: true
    }
  },
  mounted() {
    document.addEventListener('click', this.handleClickOutside)
    // 监听窗口大小变化
    window.addEventListener('resize', this.handleResize);
    this.handleResize();
  },
  beforeUnmount() {
    document.removeEventListener('click', this.handleClickOutside)
    window.removeEventListener('resize', this.handleResize);
  }
}
</script>

<style scoped>
.ai-chat-container {
  display: flex;
  height: calc(100vh - 70px); /* 减去顶部菜单的高度 */
  margin-top: 50px; 
  background: var(--bg-color);
  color: var(--text-color);
}

/* 侧边栏样式 */
.sidebar {
  width: 280px;
  background: var(--sidebar-bg);
  border-right: 1px solid var(--border-color);
  padding: 20px;
  display: flex;
  flex-direction: column;
  transition: all 0.3s ease;
  position: relative;
}

.sidebar.collapsed {
  width: 60px;
  padding: 20px 10px;
}

/* 收缩按钮样式 */
.collapse-btn {
  position: absolute;
  right: -12px;
  top: 20px;
  width: 24px;
  height: 24px;
  border-radius: 50%;
  background: var(--primary-color);
  color: white;
  border: none;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  z-index: 10;
  transition: all 0.3s ease;
}

.collapse-btn:hover {
  transform: scale(1.1);
}

/* 新建对话按钮样式 */
.new-chat-btn {
  background: var(--primary-color);
  color: white;
  border: none;
  padding: 12px;
  border-radius: 8px;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  font-weight: 500;
  transition: all 0.3s ease;
  white-space: nowrap;
  overflow: hidden;
}

.sidebar.collapsed .new-chat-btn {
  padding: 12px 0;
  width: 40px;
}

/* 模型选择器样式 */
.model-selector {
  margin: 20px 0;
}

.model-select {
  width: 100%;
  padding: 8px 12px;
  border: 1px solid var(--border-color);
  border-radius: 6px;
  background: var(--input-field-bg);
  color: var(--text-color);
  font-size: 14px;
  cursor: pointer;
  transition: all 0.3s ease;
}

.model-select:focus {
  outline: none;
  border-color: var(--primary-color);
  box-shadow: 0 0 0 2px var(--primary-color-light);
}

/* 历史记录项样式调整 */
.history-item {
  padding: 12px;
  border-radius: 8px;
  cursor: pointer;
  display: flex;
  align-items: center;
  gap: 8px;
  transition: all 0.3s ease;
  white-space: nowrap;
  overflow: hidden;
}

.sidebar.collapsed .history-item {
  padding: 12px 0;
  justify-content: center;
}

.sidebar.collapsed .history-item i {
  margin: 0;
}

/* 设置按钮样式调整 */
.settings-btn {
  background: var(--button-bg);
  border: none;
  border-radius: 50%;
  width: 44px;
  height: 44px;
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--primary-color);
  font-size: 1.4em;
  cursor: pointer;
  transition: all 0.3s ease;
}

.sidebar.collapsed .settings-btn {
  width: 40px;
  height: 40px;
  font-size: 1.2em;
}

/* 聊天区域样式 */
.chat-area {
  flex: 1;
  display: flex;
  flex-direction: column;
  position: relative;
  height: 100%;
  overflow: hidden;
}

.messages {
  flex: 1;
  overflow-y: auto;
  padding: 20px;
  display: flex;
  flex-direction: column;
  gap: 20px;
  -webkit-overflow-scrolling: touch; /* 增加 iOS 滚动流畅度 */
}

.message {
  max-width: 80%;
  word-break: break-word;
}

.message.user {
  align-self: flex-end;
}

.message.assistant {
  align-self: flex-start;
}

.message-content {
  width: 100%;
  box-sizing: border-box;
  border-radius: 12px;
  overflow: hidden;
  background: var(--message-bg);
  padding: 16px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}

.message.user .message-content {
  background: var(--primary-color);
  color: white;
}

/* 修复markdown内容溢出问题 */
.message-content .text,
.message-content .text * {
  max-width: 100%;
  word-break: break-all;
  overflow-wrap: break-word;
  box-sizing: border-box;
}

.message-content .text ul,
.message-content .text ol {
  margin-left: 1.2em;
  margin-right: 0;
  padding-left: 1.2em;
}

.message-content .text pre,
.message-content .text code {
  max-width: 100%;
  overflow-x: auto;
  background: #f6f8fa;
  border-radius: 6px;
  padding: 6px 10px;
  box-sizing: border-box;
}

.message-content .text table {
  max-width: 100%;
  overflow-x: auto;
  display: block;
  border-radius: 6px;
  background: #f6f8fa;
}

.message-content .text img {
  max-width: 100%;
  height: auto;
  border-radius: 6px;
  display: block;
}

.message-header {
  display: flex;
  justify-content: space-between;
  margin-bottom: 8px;
  font-size: 0.9em;
  opacity: 0.8;
}

/* 输入区域样式 */
.input-area {
  padding: 20px;
  background: var(--input-bg);
  border-top: 1px solid var(--border-color);
  flex-shrink: 0; /* 防止输入区域被压缩 */
}

.input-options {
  display: flex;
  justify-content: space-between;
  margin-bottom: 12px;
}

.left-options {
  display: flex;
  align-items: center;
  gap: 12px;
}

.file-upload {
  position: relative;
}

.workflow-entry {
  display: flex;
  align-items: center;
}

.workflow-btn {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 8px 16px;
  border-radius: 20px;
  background: var(--button-bg);
  color: var(--text-color);
  text-decoration: none;
  transition: all 0.3s ease;
}

.workflow-btn:hover {
  background: var(--button-hover-bg);
  color: var(--primary-color);
}

.workflow-btn i {
  color: var(--primary-color);
}

.mcp-service {
  display: flex;
  align-items: center;
}

.input-box {
  display: flex;
  gap: 12px;
}

textarea {
  flex: 1;
  padding: 12px;
  border: 1px solid var(--border-color);
  border-radius: 8px;
  resize: none;
  height: 60px;
  background: var(--input-field-bg);
  color: var(--text-color);
  transition: all 0.3s ease;
}

textarea:focus {
  outline: none;
  border-color: var(--primary-color);
  box-shadow: 0 0 0 2px var(--primary-color-light);
}

.send-btn {
  width: 48px;
  height: 48px;
  border-radius: 24px;
  border: none;
  background: var(--primary-color);
  color: white;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: all 0.3s ease;
}

.send-btn:hover:not(:disabled) {
  transform: scale(1.05);
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2);
}

.send-btn:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

/* 连接状态样式 */
.connection-status {
  position: absolute;
  top: 90px; /* 调整连接状态指示器位置 */
  right: 20px;
  padding: 8px 16px;
  border-radius: 20px;
  background: var(--status-bg);
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 0.9em;
  transition: all 0.3s ease;
}

.connection-status.connecting {
  background: var(--warning-color);
  color: white;
}

.connection-status.connected {
  background: var(--success-color);
  color: white;
}

.connection-status.disconnected {
  background: var(--error-color);
  color: white;
}

/* 错误消息样式 */
.error-message {
  position: absolute;
  top: 90px; /* 调整错误消息位置 */
  left: 50%;
  transform: translateX(-50%);
  padding: 12px 24px;
  background: var(--error-color);
  color: white;
  border-radius: 8px;
  display: flex;
  align-items: center;
  gap: 12px;
  animation: slideDown 0.3s ease;
}

/* 打字指示器样式 */
.typing-indicator {
  display: flex;
  gap: 4px;
  padding: 8px;
}

.typing-indicator span {
  width: 8px;
  height: 8px;
  background: var(--primary-color);
  border-radius: 50%;
  animation: typing 1s infinite alternate;
}

.typing-indicator span:nth-child(2) {
  animation-delay: 0.2s;
}

.typing-indicator span:nth-child(3) {
  animation-delay: 0.4s;
}

/* 动画 */
@keyframes messageSlide {
  from {
    opacity: 0;
    transform: translateY(20px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

@keyframes slideDown {
  from {
    opacity: 0;
    transform: translate(-50%, -20px);
  }
  to {
    opacity: 1;
    transform: translate(-50%, 0);
  }
}

@keyframes typing {
  0%, 100% {
    transform: translateY(0);
  }
  50% {
    transform: translateY(-4px);
  }
}

/* 响应式设计 */
@media (max-width: 768px) {
  .ai-chat-container {
    height: calc(100vh - 50px);
    margin-top: 50px;
    position: relative;
    display: flex;
    flex-direction: column;
  }

  .mobile-menu-btn {
    display: flex;
    align-items: center;
    justify-content: center;
  }

  .mobile-overlay {
    display: block;
  }

  .sidebar {
    position: fixed;
    top: 50px;
    left: 0;
    bottom: 0;
    z-index: 999;
    transform: translateX(-100%);
    transition: transform 0.3s ease;
  }

  .sidebar.mobile-active {
    transform: translateX(0);
  }

  .sidebar.collapsed {
    width: 60px;
    transform: translateX(-100%);
  }

  .sidebar.mobile-active.collapsed {
    transform: translateX(0);
  }

  .collapse-btn {
    display: none;
  }

  .chat-area {
    flex: 1;
    display: flex;
    flex-direction: column;
    height: calc(100vh - 50px - 120px); /* 减去顶部导航和底部输入框的高度 */
    overflow: hidden;
  }

  .messages {
    flex: 1;
    overflow-y: auto;
    padding: 15px;
    padding-bottom: 80px; /* 为底部输入框留出空间 */
    -webkit-overflow-scrolling: touch;
  }

  .input-area {
    position: fixed;
    bottom: 0;
    left: 0;
    right: 0;
    background: var(--bg-color);
    border-top: 1px solid var(--border-color);
    padding: 10px;
    z-index: 100;
    height: auto;
    min-height: 120px; /* 确保输入区域有足够高度 */
  }

  .input-box {
    flex-direction: column;
    gap: 8px;
  }

  textarea {
    min-height: 40px;
    max-height: 80px; /* 限制输入框最大高度 */
    padding: 8px;
    overflow-y: auto;
  }

  /* 确保消息内容在移动端正确显示 */
  .message {
    max-width: 95%;
  }

  .message-content {
    border-radius: 10px;
    padding: 10px;
  }

  .message-content .text pre,
  .message-content .text code,
  .message-content .text table {
    border-radius: 5px;
    padding: 4px 6px;
  }

  /* 优化滚动条样式 */
  .messages::-webkit-scrollbar {
    width: 4px;
  }

  .messages::-webkit-scrollbar-track {
    background: transparent;
  }

  .messages::-webkit-scrollbar-thumb {
    background: var(--border-color);
    border-radius: 2px;
  }
}

/* 确保消息内容在移动端正确显示 */
.message {
  max-width: 90%;
  word-break: break-word;
}

.message-content {
  padding: 12px;
}

/* 优化移动端输入框 */
textarea {
  min-height: 40px;
  max-height: 120px;
  padding: 8px;
}

.send-btn {
  width: 40px;
  height: 40px;
}

/* 确保设置弹窗在移动端正确显示 */
.settings-modal {
  width: 90%;
  max-width: 500px;
  max-height: 80vh;
  margin: 20px auto;
}

.settings-modal.fullscreen {
  width: 100%;
  height: 100%;
  margin: 0;
  border-radius: 0;
}

/* MCP服务状态点 */
.status-dot {
  display: inline-block;
  width: 10px;
  height: 10px;
  border-radius: 50%;
  margin-left: 8px;
  background: #ccc;
  vertical-align: middle;
  box-shadow: 0 0 2px #888;
}
.status-dot.connected {
  background: #10b981;
}
.status-dot.disconnected {
  background: #ef4444;
}
.status-dot.connecting {
  background: #f59e0b;
}

/* AI消息操作icon */
.msg-icons {
  float: right;
  margin-left: 10px;
}
.msg-icons i {
  margin-left: 8px;
  cursor: pointer;
  color: #888;
  transition: color 0.2s;
}
.msg-icons i:hover {
  color: var(--primary-color);
}

/* AI长回复等待动画 */
.ai-loading {
  display: flex;
  align-items: center;
  justify-content: flex-start;
  padding: 16px;
  gap: 4px;
}
.ai-loading .dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--primary-color);
  animation: ai-dot-bounce 1s infinite alternate;
}
.ai-loading .dot:nth-child(2) {
  animation-delay: 0.2s;
}
.ai-loading .dot:nth-child(3) {
  animation-delay: 0.4s;
}
@keyframes ai-dot-bounce {
  0%, 100% { transform: translateY(0); }
  50% { transform: translateY(-8px); }
}

/* 侧边栏底部设置icon */
.sidebar-footer {
  margin-top: auto;
  padding: 20px 0 0 0;
  display: flex;
  justify-content: center;
}

/* 设置弹窗遮罩 */
.settings-modal-mask {
  position: fixed;
  left: 0; top: 0; right: 0; bottom: 0;
  background: rgba(0,0,0,0.25);
  z-index: 2000;
  display: flex;
  align-items: center;
  justify-content: center;
}
.settings-modal {
  display: flex;
  flex-direction: column;
  min-width: 480px;
  max-width: 90vw;
  min-height: 320px;
  border-radius: 18px;
  box-shadow: 0 8px 40px rgba(80,80,120,0.18);
  background: #fff;
  overflow: hidden;
  animation: modalPop 0.25s cubic-bezier(.4,2,.6,1) both;
}
.settings-modal.fullscreen {
  position: fixed;
  left: 0; top: 0; right: 0; bottom: 0;
  min-width: 100vw;
  min-height: 100vh;
  max-width: 100vw;
  max-height: 100vh;
  border-radius: 0;
  z-index: 3001;
}
.modal-macbar {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 18px 0 0 18px;
  height: 32px;
  user-select: none;
}
.mac-dot {
  width: 14px;
  height: 14px;
  border-radius: 50%;
  display: inline-block;
  margin-right: 2px;
  box-shadow: 0 1px 2px rgba(0,0,0,0.08);
  border: 1.5px solid #fff;
  cursor: pointer;
  transition: box-shadow 0.2s;
}
.mac-dot-red { background: #ff5f56; }
.mac-dot-yellow { background: #ffbd2e; }
.mac-dot-green { background: #27c93f; }
.mac-dot:hover { box-shadow: 0 0 0 2px #eee; }
.modal-body {
  display: flex;
  flex: 1;
  min-height: 0;
  height: 100%;
}
.modal-menu {
  width: 140px;
  background: #f7f7fa;
  border-right: 1px solid #eee;
  display: flex;
  flex-direction: column;
  padding: 18px 0;
  gap: 4px;
}
.modal-menu-item {
  padding: 12px 18px;
  cursor: pointer;
  color: #666;
  font-weight: 500;
  border-left: 3px solid transparent;
  transition: background 0.2s, color 0.2s, border-color 0.2s;
}
.modal-menu-item.active {
  background: #eef2ff;
  color: var(--primary-color);
  border-left: 3px solid var(--primary-color);
}
.modal-content-area {
  flex: 1;
  padding: 32px 32px 24px 32px;
  overflow-y: auto;
}
@media (max-width: 768px) {
  .settings-modal {
    min-width: 98vw;
    max-width: 100vw;
    min-height: 90vh;
    border-radius: 8px;
  }
  .modal-menu {
    width: 90px;
    padding: 8px 0;
  }
  .modal-content-area {
    padding: 16px 8px 12px 8px;
  }
}
.modal-title {
  font-size: 1.2em;
  font-weight: 600;
  color: var(--primary-color);
  display: flex;
  align-items: center;
  gap: 8px;
}
.modal-close {
  background: none;
  border: none;
  color: #888;
  font-size: 1.2em;
  cursor: pointer;
  transition: color 0.2s;
}
.modal-close:hover {
  color: var(--primary-color);
}
.modal-placeholder {
  color: #aaa;
  font-size: 1em;
  padding: 24px 0;
  text-align: center;
}
.run-html-btn {
  margin: 10px 0 0 0;
  padding: 6px 18px;
  background: var(--primary-color);
  color: #fff;
  border: none;
  border-radius: 6px;
  font-size: 0.98em;
  cursor: pointer;
  transition: background 0.2s;
}
.run-html-btn:hover {
  background: #4338ca;
}
.html-block {
  margin-bottom: 18px;
}
.html-runner-modal-mask {
  position: fixed;
  left: 0; top: 0; right: 0; bottom: 0;
  background: rgba(0,0,0,0.25);
  z-index: 3000;
  display: flex;
  align-items: center;
  justify-content: center;
}
.html-runner-modal {
  background: #fff;
  border-radius: 18px;
  min-width: 420px;
  max-width: 90vw;
  min-height: 320px;
  box-shadow: 0 8px 32px rgba(0,0,0,0.18);
  padding: 0;
  overflow: hidden;
  display: flex;
  flex-direction: column;
}
.html-runner-iframe {
  width: 600px;
  max-width: 80vw;
  height: 400px;
  border: none;
  background: #fafafa;
  margin: 0 auto 24px auto;
  border-radius: 8px;
}
@media (max-width: 768px) {
  .html-runner-modal {
    min-width: 90vw;
    border-radius: 12px;
  }
  .html-runner-iframe {
    width: 90vw;
    height: 240px;
  }
}
.run-html-icon {
  color: #10b981;
  margin-right: 8px;
  cursor: pointer;
  transition: color 0.2s, opacity 0.2s;
}
.run-html-icon.disabled {
  color: #bbb;
  cursor: not-allowed;
  opacity: 0.5;
  pointer-events: none;
}
.ai-loading-full {
  position: fixed;
  left: 0; top: 0; right: 0; bottom: 0;
  background: var(--bg-color);
  z-index: 3000;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
}

/* 移动端菜单按钮 */
.mobile-menu-btn {
  display: none;
  position: fixed;
  top: 60px;
  left: 10px;
  z-index: 1000;
  background: var(--primary-color);
  color: white;
  border: none;
  border-radius: 50%;
  width: 40px;
  height: 40px;
  font-size: 1.2em;
  cursor: pointer;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2);
}

/* 移动端遮罩层 */
.mobile-overlay {
  display: none;
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: rgba(0, 0, 0, 0.5);
  z-index: 998;
}

/* 响应式布局调整 */
@media (max-width: 768px) {
  .ai-chat-container {
    height: calc(100vh - 50px);
    margin-top: 50px;
    position: relative;
    display: flex;
    flex-direction: column;
  }

  .mobile-menu-btn {
    display: flex;
    align-items: center;
    justify-content: center;
  }

  .mobile-overlay {
    display: block;
  }

  .sidebar {
    position: fixed;
    top: 50px;
    left: 0;
    bottom: 0;
    z-index: 999;
    transform: translateX(-100%);
    transition: transform 0.3s ease;
  }

  .sidebar.mobile-active {
    transform: translateX(0);
  }

  .sidebar.collapsed {
    width: 60px;
    transform: translateX(-100%);
  }

  .sidebar.mobile-active.collapsed {
    transform: translateX(0);
  }

  .collapse-btn {
    display: none;
  }

  .chat-area {
    flex: 1;
    display: flex;
    flex-direction: column;
    height: calc(100vh - 50px - 120px); /* 减去顶部导航和底部输入框的高度 */
    overflow: hidden;
  }

  .messages {
    flex: 1;
    overflow-y: auto;
    padding: 15px;
    padding-bottom: 80px; /* 为底部输入框留出空间 */
    -webkit-overflow-scrolling: touch;
  }

  .input-area {
    position: fixed;
    bottom: 0;
    left: 0;
    right: 0;
    background: var(--bg-color);
    border-top: 1px solid var(--border-color);
    padding: 10px;
    z-index: 100;
    height: auto;
    min-height: 120px; /* 确保输入区域有足够高度 */
  }

  .input-box {
    flex-direction: column;
    gap: 8px;
  }

  textarea {
    min-height: 40px;
    max-height: 80px; /* 限制输入框最大高度 */
    padding: 8px;
    overflow-y: auto;
  }

  /* 确保消息内容在移动端正确显示 */
  .message {
    max-width: 95%;
  }

  .message-content {
    border-radius: 10px;
    padding: 10px;
  }

  .message-content .text pre,
  .message-content .text code,
  .message-content .text table {
    border-radius: 5px;
    padding: 4px 6px;
  }

  /* 优化滚动条样式 */
  .messages::-webkit-scrollbar {
    width: 4px;
  }

  .messages::-webkit-scrollbar-track {
    background: transparent;
  }

  .messages::-webkit-scrollbar-thumb {
    background: var(--border-color);
    border-radius: 2px;
  }
}

/* AI消息底部提示样式 */
.ai-warning {
  margin-top: 12px;
  padding: 8px 12px;
  background: #fff3cd;
  border: 1px solid #ffeeba;
  border-radius: 6px;
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 0.9em;
  color: #856404;
  box-sizing: border-box;
}

.warning-icon {
  width: 20px;
  height: 20px;
  background: #ffc107;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  color: #fff;
  font-size: 0.9em;
  flex-shrink: 0;
}

.warning-text {
  line-height: 1.4;
}

/* 确保警告提示在用户消息中不显示 */
.message.user .ai-warning {
  display: none;
}

/* 移动端适配 */
@media (max-width: 768px) {
  .ai-warning {
    margin-top: 8px;
    padding: 6px 10px;
    font-size: 0.85em;
  }

  .warning-icon {
    width: 18px;
    height: 18px;
    font-size: 0.85em;
  }
}

/* 推荐问题样式 */
.suggested-questions {
  margin-top: 16px;
  padding: 12px;
  background: var(--bg-color);
  border-radius: 8px;
  border: 1px solid var(--border-color);
}

.suggested-title {
  display: flex;
  align-items: center;
  gap: 8px;
  color: var(--primary-color);
  font-weight: 500;
  margin-bottom: 12px;
}

.suggested-title i {
  color: #ffd700;
}

.questions-list {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.question-item {
  padding: 6px 12px;
  background: var(--button-bg);
  border-radius: 16px;
  font-size: 0.9em;
  cursor: pointer;
  display: flex;
  align-items: center;
  gap: 6px;
  transition: all 0.2s ease;
}

.question-item:hover {
  background: var(--primary-color);
  color: white;
}

.question-item i {
  font-size: 0.9em;
  opacity: 0.7;
}

/* 移动端适配 */
@media (max-width: 768px) {
  .questions-list {
    flex-direction: column;
  }
  
  .question-item {
    width: 100%;
  }
}

/* MCP设置表单样式 */
.settings-form {
  padding: 16px 0;
}

.form-group {
  margin-bottom: 20px;
}

.form-group label {
  display: block;
  margin-bottom: 8px;
  color: #333;
  font-weight: 500;
}

.form-group label.required::after {
  content: "*";
  color: #ff4d4f;
  margin-left: 4px;
}

.form-input {
  width: 100%;
  padding: 8px 12px;
  border: 1px solid var(--border-color);
  border-radius: 6px;
  font-size: 14px;
  transition: all 0.3s;
}

.form-input:focus {
  outline: none;
  border-color: var(--primary-color);
  box-shadow: 0 0 0 2px var(--primary-color-light);
}

.args-list, .env-list {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.arg-item, .env-item {
  display: flex;
  gap: 8px;
  align-items: center;
}

.env-key {
  width: 120px;
  flex-shrink: 0;
}

.remove-btn {
  width: 32px;
  height: 32px;
  border: none;
  background: none;
  color: #999;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 4px;
  transition: all 0.3s;
}

.remove-btn:hover {
  color: #ff4d4f;
  background: #fff1f0;
}

.add-arg-btn, .add-env-btn {
  margin-top: 8px;
  padding: 8px 16px;
  border: 1px dashed var(--border-color);
  background: none;
  border-radius: 6px;
  color: var(--primary-color);
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  transition: all 0.3s;
}

.add-arg-btn:hover, .add-env-btn:hover {
  border-color: var(--primary-color);
  background: var(--primary-color-light);
}

/* 移动端适配 */
@media (max-width: 768px) {
  .env-item {
    flex-direction: column;
    gap: 8px;
  }
  
  .env-key {
    width: 100%;
  }
  
  .remove-btn {
    align-self: flex-end;
  }
}
</style> 